9 #define foreachin(it,s) for (typeof(s.begin()) it = (s).begin(); it != (s).end(); it++)
10 #define forn(i,n) for(unsigned short i = 0; i < (n); i++)
24 inline union_find(unsigned short n
){
26 for(unsigned short i
=0;i
<n
;i
++){
32 ~union_find(){delete[] S
;}
34 inline void Union(unsigned short a
, unsigned short b
){ //use Union because union is a keyword :P
35 unsigned short ranka
,rankb
;
36 ranka
=S
[a
].parent
->rank
;
37 rankb
=S
[b
].parent
->rank
;
39 (S
[b
].parent
)->parent
=S
[a
].parent
;
40 S
[a
].rank
=ranka
+rankb
;
43 (S
[a
].parent
)->parent
=S
[b
].parent
;
44 S
[b
].rank
=ranka
+rankb
;
48 inline void compress_path(uf_node
* temp
, uf_node
* aux
, uf_node
* stop_point
){
50 aux
->parent
=stop_point
;
52 while(aux
!=stop_point
){
54 aux
->parent
=stop_point
;
59 inline unsigned short Find(unsigned short a
){
62 unsigned short result
;
73 compress_path(temp
,aux
,stop_point
);
81 unsigned short start
,end
;
83 inline edge(unsigned short start
, unsigned short end
, unsigned short cost
){
91 inline bool compare(const edge
& a
,const edge
& b
){
92 return a
.cost
< b
.cost
;
96 inline void bucket_sort(list
<edge
>& e
,unsigned short max_cost
){
97 vector
<list
<edge
> > v(max_cost
+1);
99 const edge
& ed
= e
.front();
100 v
[ed
.cost
].push_back(ed
);
104 while(!v
[i
].empty()){
105 e
.push_back(v
[i
].back());
112 inline unsigned short kruskal(list
<edge
>& e
,unsigned short n
, vector
<list
<edge
> >& adj
,list
<edge
>& rejected
, unsigned short max_cost
, unsigned short m
){
114 unsigned short res
=0;
116 bucket_sort(e
,max_cost
);
125 if(list
.Find(s
)==list
.Find(f
)){
127 rejected
.push_back(*it
);
133 adj
[s
].push_back(*it
);
134 adj
[f
].push_back(edge(it
->end
,it
->start
,it
->cost
));
143 inline void dfs_fill_max(unsigned short u
, unsigned short x
,vector
<list
<edge
> >& mst_adjacency
, vector
<vector
<edge
*> >& max
){
144 foreachin(v
,(mst_adjacency
[x
])){
145 if( max
[u
][v
->end
] == NULL
&& v
->end
!= u
){
146 if(x
==u
|| v
->cost
> max
[u
][x
]->cost
){
147 max
[u
][v
->end
] = &(*v
);
150 max
[u
][v
->end
] = max
[u
][x
];
152 dfs_fill_max(u
,v
->end
,mst_adjacency
,max
);
158 inline unsigned short second_mst(unsigned short n
, vector
<list
<edge
> >& mst_adjacency
, list
<edge
>& rejected
,unsigned short minimum_cost
){
159 vector
<vector
<edge
*> > max(n
,vector
<edge
*>(n
,NULL
));
160 list
<edge
>::iterator it
= rejected
.begin();
161 unsigned short start
= it
->start
;
162 unsigned short end
= it
->end
;
163 dfs_fill_max(start
,start
,mst_adjacency
, max
);
164 unsigned short old_cost
=max
[start
][end
]->cost
;
165 unsigned short new_cost
=it
->cost
;
166 unsigned short minimum
= new_cost
- old_cost
;
168 for(it
;it
!= rejected
.end();it
++ ){
171 if(max
[start
][end
] == NULL
)dfs_fill_max(start
,start
,mst_adjacency
, max
);
173 unsigned short aux
=it
->cost
- max
[start
][end
]->cost
;
175 if(aux
== 0)return minimum_cost
;
178 old_cost
= max
[start
][end
]->cost
;
182 return minimum_cost
- old_cost
+ new_cost
;
191 unsigned short from
,to
,cost
;
195 scanf("%hu %hu",&n
,&m
);
196 vector
<list
<edge
> > mst_adjacency(n
);
199 unsigned short cant_edges
=0;
200 unsigned short max_cost
= 0;
201 while(cant_edges
< m
){
202 scanf("%hu %hu %hu",&from
,&to
,&cost
);
203 if(cost
> max_cost
)max_cost
= cost
;
204 l
.push_back(edge(from
-1,to
-1,cost
));
207 unsigned short k
=kruskal(l
,n
,mst_adjacency
,rejected
,max_cost
,m
);
208 //unsigned short k =kruskal(l,n,mst_adjacency,rejected);
210 cout
<< second_mst(n
,mst_adjacency
,rejected
,k
)<<endl
;